#!/usr/bin/perl

######################################################################
package Swignition::Misc;
######################################################################

# Miscellaneous variables and functions mostly used by swignitiond.pl and
# swignition.pl.

use strict;
use utf8;
use Clone qw(clone);
use JSON;
use XML::LibXML;
use XML::LibXSLT;

my $perlvar = $^V; $perlvar =~ s/^v//;

our $defaultBaseURI = 'http://example.com/';
our $version        = '0.1-alpha16';
our $releaseDate    = '2009-02-28';
our $uaString       = "swignition/$version ($releaseDate) perl/$perlvar ($^O) "
                    . sprintf('libxml/%s ', XML::LibXML::LIBXML_DOTTED_VERSION)
                    . sprintf('libxslt/%s ', XML::LibXSLT::LIBXSLT_DOTTED_VERSION);
our $acceptHeader = 'application/xhtml+xml, '
		. 'text/html, '
		. 'application/rdf+xml, '
		. 'text/rdf, '
		. 'application/x-turtle, '
		. 'application/rdf+turtle, '
		. 'application/turtle, '
		. 'text/turtle, '
		. 'text/n3, '
		. 'text/rdf+n3, '
		. 'application/json, '
		. 'application/xml, '
		. 'text/xml';

our $UA = undef;

sub url_split
{
	my $url = shift;
	
	if ($url =~ /^([^\#]+)\#subject\((.*)\)$/)
	{
		return ("$1", "$2");
	}
	elsif ($url =~ /^([^\#]+)\#(.*)$/)
	{
		return ("$1", "$1#$2");
	}
	else
	{
		return ($url, undef);
	}
}


sub get_ua
{
	$Swignition::Misc::UA = LWP::UserAgent->new(agent => $Swignition::Misc::uaString, parse_head => 0 )
		unless $Swignition::Misc::UA;	
	$Swignition::Misc::UA->default_headers->header('Accept' => $Swignition::Misc::acceptHeader);
	return $Swignition::Misc::UA;
}


sub do_export
{
	my ($output_format, $parser, $subjectUrl, $graph_uri) = @_;
	
	my $graph = $parser->model->combined_graph;
	$graph = $parser->graph($graph_uri)
		if length $graph_uri;
	
	use Data::Dumper;
	print Dumper($parser->{'Data'}->{'model'}->combined_graph->as_json('g'));
	exit;

	if ($output_format =~ /uf-json/i)
	{
		*UNIVERSAL::TO_JSON = sub {
			my $object = shift;
			
			return "$object"
				if ((ref $object) =~ /^(Swignition..Magic|DateTime)/);

			return undef
				if ((ref $object) =~ /^(XML..LibXML)/);
			
			my $clone  = {};
			foreach my $k (keys %$object)
			{
				$clone->{$k} = $object->{$k}
					unless $k =~ /^(_.+|[A-Z]+|isInCal|isTheRoot|associated_hevent|parent_property_node)$/;
			}
			return $clone;
		};
		my $json = to_json({
			'microformats' => {
				'vcard'           => $parser->{'uF'}->{'hCard'},
				'figure'          => $parser->{'uF'}->{'figure'},
				'adr'             => $parser->{'uF'}->{'adr'},
				'geo'             => $parser->{'uF'}->{'geo'},
				'vcalendar'       => $parser->{'uF'}->{'hCalendar'},
				'rel-license'     => $parser->{'uF'}->{'License'},
				'rel-enclosure'   => $parser->{'uF'}->{'Enclosure'},
				'rel-tag'         => $parser->{'uF'}->{'Tag'},
				'haudio'          => $parser->{'uF'}->{'hAudio'},
				'hmeasure'        => $parser->{'uF'}->{'hMeasure'},
				'hresume'         => $parser->{'uF'}->{'hResume'},
				'hrecipe'         => $parser->{'uF'}->{'hRecipe'},
				'hreview'         => $parser->{'uF'}->{'hReview'},
				'hfeed'           => $parser->{'uF'}->{'hAtom'},
				'xfn'             => $parser->{'uF'}->{'XFN'}
			},
			'parser-info' => {
				'name'            => 'Swignition',
				'version'         => $Swignition::Misc::version,
				'page-url'        => $parser->uri
			}
		}, {
			'utf8'            => 1,
			'pretty'          => 1,
			'allow_nonref'    => 1,
			'allow_blessed'   => 1,
			'convert_blessed' => 1,
		});
		
		return "$json\n";
	}
	
	elsif ($output_format =~ /vcf/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Contact::outVCF($parser, $graph, $subjectUrl); }
		else
			{ return Swignition::Export::Contact::multiVCF($parser, $graph); }
	}
	
	elsif ($output_format =~ /rdf.?json/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Entity::outJSON($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Entity::multiJSON($parser->{RDF}); }
	}
	
	elsif ($output_format =~ /turtle/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Entity::outTurtle($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Entity::multiTurtle($parser->{RDF}); }
	}
	
	elsif ($output_format =~ /n3/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Entity::outN3($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Entity::multiN3($parser->{RDF}); }
	}
	
	elsif ($output_format =~ /trix/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Entity::outTriX($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Entity::multiTriX($parser->{RDF}); }
	}
	
	elsif ($output_format =~ /recipebook/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Recipe::outRecipeBook($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Recipe::multiRecipeBook($parser->{RDF}); }
	}
	
	elsif ($output_format =~ /kml/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Location::outKML($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Location::multiKML($parser->{RDF}); }
	}

	elsif ($output_format =~ /m3u/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Recording::outM3U($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Recording::multiM3U($parser->{RDF}); }
	}
		
	elsif ($output_format =~ /detect/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Entity::outDetect($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Entity::multiDetect($parser->{RDF}); }
	}
	
	elsif ($output_format =~ /jcard/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Contact::outJSON($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Contact::multiJSON($parser->{RDF}); }
	}

	elsif ($output_format =~ /atom/i)
	{
		if ($subjectUrl)
			{ return Swignition::Export::Feed::outAtom($parser->{RDF}, $subjectUrl); }
		else
		{
			foreach my $subj (keys %{$parser->{RDF}})
			{
				if ( Swignition::Export::Feed::is($parser->{RDF}->{$subj}) )
				{
					return Swignition::Export::Feed::outAtom($parser->{RDF}, $subj);
				}
			}
		}
	}
	
	elsif ($output_format =~ /ics/i)
	{
		if ($subjectUrl)
		{
			if (Swignition::Export::Calendar::is($parser->{RDF}, $subjectUrl))
				{ return Swignition::Export::Calendar::outICS($parser->{RDF}, $subjectUrl); }
			elsif (Swignition::Export::CalComponent::is($parser->{RDF}, $subjectUrl))
				{ return Swignition::Export::CalComponent::outICS($parser->{RDF}, $subjectUrl); }
		}
		else
			{ return Swignition::Export::Calendar::multiICS($parser->{RDF}); }
	}
	
	else
	{
		if ($subjectUrl)
			{ return Swignition::Export::Entity::outRDF($parser->{RDF}, $subjectUrl); }
		else
			{ return Swignition::Export::Entity::multiRDF($parser->{RDF}); }
	}
}


1;
